Conversation
Complete frontend rebuild of ClawHub into a marketplace-style discovery hub inspired by HuggingFace and npm. No backend changes. Navigation: - Two-row header: brand + search bar + user actions on top, content type tabs (Skills, Plugins) with count badges below - Inline search in navbar navigates to /search - Mobile: search collapses behind icon, tabs scroll horizontally Home page: - Value-prop hero with Browse/Publish CTAs (no duplicate search) - Trending section (8 skills by downloads) - Recently updated section (8 skills by update time) - Staff picks grid (6 highlighted skill cards) - Browse by category grid (8 categories with Lucide icons) - Skeleton loading rows while data fetches Browse pages (Skills + Plugins): - Full-width search bar above sidebar+results grid - Left sidebar with sort options, categories, filter checkboxes (proper ARIA: fieldset/legend, role=radiogroup, aria-checked) - List view uses compact SkillListItem rows (owner/name/summary/meta) - Card view with hover border feedback - View toggle (List/Cards) - Better empty states with guidance text Skill detail page: - README tab as default (was Files) - Two-column layout: tabs+comments on left, metadata sidebar on right - Removed duplicate README from Files tab - Removed duplicate Download button from header (kept in sidebar) - Removed SkillInstallCard from header (license info in sidebar) - Nix/config snippets moved inside two-column layout - Friendly "No README available" instead of raw Convex errors Unified search (/search): - Real search results page (was redirect-only) - Type tabs: All / Skills / Plugins with counts - useUnifiedSearch hook fires skill search + plugin catalog in parallel - Consistent SkillListItem rendering for results Dashboard: - Welcome state for new users with empty dashboard - Simplified header copy Profiles & Footer: - Richer user profiles: large avatar, stat row, SkillListItem for published/starred skills - Multi-column footer: Browse / Publish / Community / Platform Design system: - Spacing tokens: --space-1 (4px) through --space-8 (64px) - Typography scale: --fs-xs through --fs-3xl (8 values, was 42) - Radius tokens: --r-lg/md/sm/xs/pill (renamed from --radius-* to avoid Tailwind CSS v4 variable collision) - Flat buttons (killed gradient, removed hover lift/shadow) - Complete markdown styles: tables, blockquotes, lists, images, hr, heading hierarchy with h1/h2 bottom borders (npm-style) - Removed decorative elements: body gradient backgrounds, card shadows, brand mark animation, category card glow New components: - SkillListItem — compact HF-style row - BrowseSidebar — faceted filter sidebar with ARIA - SkillMetadataSidebar — detail page right sidebar - useUnifiedSearch — parallel search hook - timeAgo — relative time formatter - categories — static skill category taxonomy Seed data: - seedDemo.ts with 20 realistic skills, 5 publishers - repairHighlightedBadges for skillBadges table - repairGlobalStats for correct count Test updates: - Updated 5 test files for new text, class names, and prop changes - All 122 test files, 915 tests passing
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Greptile SummaryThis PR is a large frontend rebuild that introduces a marketplace-style discovery hub (home page, browse pages, detail sidebar, unified search, design-system tokens) alongside two backend additions: a new public
Confidence Score: 3/5Not safe to merge as-is: one policy violation (seed data in source) and one TypeScript compile error both need to be resolved first. Two P1 findings: the AGENTS.md rule explicitly calls for rejecting seed-only skill additions committed to source, and the useUnifiedSearch tuple bug will cause bunx tsc --noEmit to fail (a required pre-merge check per AGENTS.md). Both block merge. The rest of the UI overhaul is well-structured, the previously-reported activeCategory and internalMutation import issues are addressed, and the convexHttp.query() usage on public pages is correct. convex/seedDemo.ts (policy violation) and src/lib/useUnifiedSearch.ts (TypeScript tuple error) Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/lib/useUnifiedSearch.ts
Line: 67-71
Comment:
**3-tuple initialized with only 2 elements — TypeScript error**
The type annotation declares a 3-element tuple but the initializer only supplies 2 elements, so `promises[2]` is `undefined` until the `users` branch sets it. TypeScript strict mode rejects this (`bunx tsc --noEmit` will fail), which AGENTS.md requires before merge. At runtime when `activeType === "plugins"` the third slot is `undefined`, but the optional-chaining in the consumer (`?.items ?? []`) masks the error silently.
```suggestion
const promises: [
Promise<unknown> | null,
Promise<{ items: PackageListItem[] }> | null,
Promise<{ items: PublicUser[] }> | null,
] = [null, null, null];
```
How can I resolve this? If you propose a fix, please make it concise.
---
This is a comment left during a code review.
Path: convex/seedDemo.ts
Line: 1-10
Comment:
**Seed data violates AGENTS.md policy — skills must be published via CLI**
AGENTS.md explicitly states:
> Reject PRs that add skills into source code/repo content directly (for example under `skills/` or seed-only additions intended as published skills). Skills must be uploaded/published via CLI.
`convex/seedDemo.ts` adds 20 demo skill records (with publishers, highlighted badges, `skillSearchDigest` entries, and `skillBadges` rows) that are meant to appear in the discovery hub as real listings. This is exactly the "seed-only additions intended as published skills" pattern the rule targets. The skills should be published via the CLI against the target environment instead of shipped as source-committed seed code.
**Context Used:** AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=a1d58d20-b4dd-4cbb-973a-9fd7824e1921))
How can I resolve this? If you propose a fix, please make it concise.Reviews (2): Last reviewed commit: "fix: audit fixes — warm colors, lint, AR..." | Re-trigger Greptile |
- Import internalMutation from convex/functions (not _generated/server) to get trigger wrapping per CLAUDE.md rules - Derive activeCategory from current search query so sidebar category selection shows correct visual/ARIA state - Push moderationStatus filter server-side in repairGlobalStats to avoid full table scan - Reset skillCount/pluginCount to 0 in useUnifiedSearch catch block to prevent stale badge values after search errors
- Remove unused imports (v, getRuntimeEnv) from seedDemo.ts and SkillHeader.tsx - Replace `as any` casts with proper Id<"publishers"> types in seedDemo.ts - Prefix unused params with underscore (_clawdis, _osLabels, _nixSystems, _listDoneLoading) - Remove unused convexSiteUrl variable from SkillHeader
- Switch light theme from warm beige (#f8f2ed) to neutral white (#fafafa) with neutral gray ink (#1a1a1a) and borders (rgba black) - Switch dark theme from warm brown to neutral dark (#111111) with neutral gray borders (rgba white) - Replace fake category grid (8 keyword-search cards) with curated quick links (Most starred, New this week, Browse plugins, Staff picks) - Add "What are skills?" explainer paragraph below hero CTAs - Add fadeIn animation on results list when data arrives - Add "Clear" button in browse results toolbar when filters are active - Tighten browse layout gap from 24px to 16px
Complete visual redesign to a dark, monochrome, terminal-inspired aesthetic inspired by Warp, modern TUI tools, and blueprint designs. Color system: - Default is now dark (#0a0a0a bg, #e0e0e0 ink, #141414 surface) - All accent colors removed — monochrome only (white as accent) - Borders use rgba(255,255,255,0.08) for subtle separation - Light theme available as optional override via [data-theme="light"] Typography: - All fonts now IBM Plex Mono (display, body, code all monospace) - Brand name is lowercase monospace - Section titles are uppercase monospace with letter-spacing - Tags and badges use monospace font Geometry: - All border-radius reduced to 1-2px (sharp TUI corners) - No shadows anywhere (--shadow: none) - No backdrop-filter blur on navbar - Cards, buttons, inputs all have sharp edges Components: - Buttons: transparent bg with border, monospace text - Primary buttons: white on black (inverted) - Tags: border-only, no colored backgrounds - Cards: dark surface with subtle border - Brand mark: 24px square instead of 28px circle Layout: - Replaced category grid with simple quick links - Removed all warm color references - Home section titles are small uppercase labels - Skill list item names use --ink (no accent color)
Theming (P0): - Removed all 78 [data-theme="dark"] override selectors (dark is now default, these were dead code with conflicting warm colors) - Replaced 56 instances of rgba(255,107,74,x) warm coral with rgba(255,255,255,x) monochrome equivalents - Replaced hard-coded warm hex colors (#c35640, #ff6b4a, etc.) with gray monochrome values - CSS file reduced from ~6300 to 5909 lines Touch targets (P1): - Added min-height: 36px to .btn (was ~24px) - Added min-height: 36px to .navbar-tab (was ~27px) - Added min-height: 32px to .sidebar-option and .sidebar-checkbox - Increased padding on buttons and tabs Accessibility (P2/P3): - Comprehensive prefers-reduced-motion: reduce rule — disables all animations AND transitions for users who prefer reduced motion - Covers shimmer, fadeIn, fadeUp, and all CSS transitions
- Home page sections only render when data arrives (no skeleton flash)
- Removed SkeletonRows component from home page (unused)
- Skeleton bars simplified: static gray bars, no shimmer animation
- Skeleton row padding matches list item padding
- Hero padding tightened (48px top → 32px)
- Hero subtitle made concise ("20 skill bundles... Browse, install, publish.")
- Removed redundant explainer paragraph
- Browse results count shows em dash while loading (not "Loading...")
- .section class uses spacing tokens
- .section-title uses monospace font at --fs-lg
- .section-subtitle uses --fs-sm
- results-list removed fadeIn animation (subtle state changes only)
- Replace ~20 remaining warm hex colors in upload/form styles (#ffddc9, #9a3a24, #fff3ec, etc.) with monochrome equivalents - Fix 2 lint errors: remove unused Link import (search.tsx), prefix unused parseDir with underscore (souls/index.tsx) - Add aria-label to PluginListItem and UserListItem for screen reader identification
| const promises: [ | ||
| Promise<unknown> | null, | ||
| Promise<{ items: PackageListItem[] }> | null, | ||
| Promise<{ items: PublicUser[] }> | null, | ||
| ] = [null, null]; |
There was a problem hiding this comment.
3-tuple initialized with only 2 elements — TypeScript error
The type annotation declares a 3-element tuple but the initializer only supplies 2 elements, so promises[2] is undefined until the users branch sets it. TypeScript strict mode rejects this (bunx tsc --noEmit will fail), which AGENTS.md requires before merge. At runtime when activeType === "plugins" the third slot is undefined, but the optional-chaining in the consumer (?.items ?? []) masks the error silently.
| const promises: [ | |
| Promise<unknown> | null, | |
| Promise<{ items: PackageListItem[] }> | null, | |
| Promise<{ items: PublicUser[] }> | null, | |
| ] = [null, null]; | |
| const promises: [ | |
| Promise<unknown> | null, | |
| Promise<{ items: PackageListItem[] }> | null, | |
| Promise<{ items: PublicUser[] }> | null, | |
| ] = [null, null, null]; |
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/lib/useUnifiedSearch.ts
Line: 67-71
Comment:
**3-tuple initialized with only 2 elements — TypeScript error**
The type annotation declares a 3-element tuple but the initializer only supplies 2 elements, so `promises[2]` is `undefined` until the `users` branch sets it. TypeScript strict mode rejects this (`bunx tsc --noEmit` will fail), which AGENTS.md requires before merge. At runtime when `activeType === "plugins"` the third slot is `undefined`, but the optional-chaining in the consumer (`?.items ?? []`) masks the error silently.
```suggestion
const promises: [
Promise<unknown> | null,
Promise<{ items: PackageListItem[] }> | null,
Promise<{ items: PublicUser[] }> | null,
] = [null, null, null];
```
How can I resolve this? If you propose a fix, please make it concise.
Summary
Complete frontend rebuild of ClawHub into a marketplace-style discovery hub inspired by HuggingFace and npm. No backend changes.
--fs-*and--r-*to avoid Tailwind CSS v4 variable collisionNew components
SkillListItem— compact HF-style rowBrowseSidebar— faceted filter sidebar with proper ARIASkillMetadataSidebar— detail page right sidebaruseUnifiedSearch— parallel search hooktimeAgo/categories— utilitiesTest plan
npx vite build— clean, no errorsnpx vitest run— 122 files, 915/915 tests passingbunx convex run seedDemo:seedDemoSkills)